#ifndef SENDCANPROTMANAGER_H
#define SENDCANPROTMANAGER_H


#include <QObject>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QFile>
#include <QMap>
#include <QByteArray>
#include <QString>

//信号配置信息结构体
struct SignalConfig {
    QString name;               // 信号名称
    QString description;        // 信号描述
    QString byteOrder;          // 字节顺序 (Intel/Motorola)
    int startByte;              // 起始字节
    int startBit;               // 起始位
    QString sendType;           // 发送类型
    int bitLength;              // 位长度
    QString dataType;           // 数据类型
    double resolution;          // 精度
    double offset;              // 偏移量
    double physMin;             // 物理最小值
    double physMax;             // 物理最大值
    QString hexMin;             // 总线最小值(hex)
    QString hexMax;             // 总线最大值(hex)
    QString initialValue;       // 初始值(hex)
    QString invalidValue;       // 无效值(hex)
    QString inactiveValue;      // 非使能值(hex)
    QString unit;               // 单位
    QString valueDescription;   // 信号值描述
};

//报文配置信息结构体
struct MessageConfig {
    QString name;               // 报文名称
    QString type;               // 报文类型
    QString id;                 // 报文ID
    QString sendType;           // 发送类型
    int cycleTime;              // 周期时间(ms)
    int length;                 // 报文长度(Byte)
    QMap<QString, SignalConfig> signalL;  // 信号配置
};


class SendCANProtManager : public QObject
{
    Q_OBJECT
public:
    //explicit SendCANProtManager(QObject *parent = nullptr);

    //加载JSON配置文件
    bool loadConfig(const QString &filePath);

    //获取所有报文名称
    QStringList getMessageNames() const;

    //生成指定报文的16进制数据
    QByteArray generateMessageData(const QString &msgName, const QMap<QString, QVariant> &signalValues);

    //获取指定报文的配置信息
    MessageConfig getMessageConfig(const QString &msgName) const;

private:
    //解析JSON配置
    void parseConfig(const QJsonObject &jsonObject);

    //计算校验和
    quint8 calculateChecksum(const QByteArray &data, const SignalConfig &checkSumSignal);

    //更新循环计数器
    quint8 updateRollingCounter(const QString &msgName);

    //将物理值转换为总线值
    quint64 physicalToRaw(const SignalConfig &signal, double physValue);

    //将值写入字节数组的指定位
    void setBits(QByteArray &data, const SignalConfig &signal, quint64 value);

    QMap<QString, MessageConfig> m_messageConfigs;  // 报文配置映射表
    QMap<QString, quint8> m_rollingCounters;       // 循环计数器映射表
};


#endif // SENDCANPROTMANAGER_H
